

import parseAPNG, { APNG } from "apng-js";
import Player from "apng-js/types/library/player";
import axios from "axios";
import { CanvasTexture } from "three";
import threeUtils from "./threeUtils";


export default class ApngTexture extends CanvasTexture {

    constructor(url: string) {
        super(document.createElement("canvas"));
        this.loadApng(url);
    }
    // 获取时间戳
    static TimeTemp = performance.now();

    // 上一次更新时间
    preUpdate = 0;

    player?: Player;

    // apng 对象
    apng?: APNG;

    // 更新纹理
    onUpdate = () => {

        if (this.preUpdate === ApngTexture.TimeTemp) {
            return;
        }

        this.preUpdate = ApngTexture.TimeTemp;

        if (this.player) {
            this.player.renderNextFrame();
        }
    };

    // 获取当前帧id
    getUuid() {

        if (this.apng) {

            let currentTime = ApngTexture.TimeTemp % this.apng.playTime;

            let i = 0;
            while (this.apng.frames[i] && currentTime > this.apng.frames[i].delay) {
                currentTime -= this.apng.frames[i].delay;
                i++;
            }

            return this.apng.frames[i].delay;

        } else {

            return "";

        }

    }

    // 加载apng图片
    async loadApng(url: string) {

        const res = await axios.get(url, { method: "post", responseType: "blob" });

        const blob = new Blob([res.data]);

        const reader = new FileReader();

        await new Promise<void>((resolve) => {
            reader.onload = () => resolve();
            reader.readAsArrayBuffer(blob);
        });

        const apng = (parseAPNG(reader.result as ArrayBuffer) as APNG);

        this.dispose();
        this.image.width = apng.width;
        this.image.height = apng.height;
        this.player = await apng.getPlayer(this.image.getContext("2d")!);
    }

}

// 定时更新时间戳
threeUtils.addEventListener("requestAnimationFrame", (e: any) => {
    ApngTexture.TimeTemp = e.timeTemp;
});